#ifndef WXI_THREADPOOL_H
#define WXI_THREADPOOL_H

#include "defs.h"
#include "wx/thread.h"
#include "wx/list.h"

class wxiTask
{
public:
	virtual ~wxiTask() {}

	virtual void Execute() = 0;

	virtual bool ShouldDelete() = 0;

	virtual bool IsLongTask() = 0;
};

#define WORKER_INC_SETUP 5

class wxiWorkerManager;

WX_DECLARE_LIST(wxiTask, wxiTaskList);

class wxiWorkThread: public wxThread, public wxObject
{
public:
	wxiWorkThread(wxiWorkerManager* manager) : wxThread(wxTHREAD_DETACHED), m_manager(manager) {}

	~wxiWorkThread() { }

private:
	void* Entry();

private:
	wxiWorkerManager* m_manager;
};

class wxiWorkerManager : public wxObject
{
public:
	wxiWorkerManager(int initcount = 5, int maxcount = 20);
	~wxiWorkerManager();

	int GetMaxCount() const { return m_maxCount; }
	void SetMaxCount(int count);
	int GetWorkerCount() const { return (int)m_workers.GetCount(); }
	int GetTaskCount();

	void AppendTask(wxiTask* task);
	void WaitForAllComplete();

	wxString GetUniqueName() const;

private:
	void Init(int initcnt);

	wxiTask* GetTask(long timeout = 0);
	void TaskDone(wxiTask* task);

	void KillAllWorker();
	void WorkerKilled(wxiWorkThread* worker);
	void IncWorker();

private:
	int m_maxCount;
	wxList m_workers;
	wxiTaskList m_tasks;

	wxMutex m_mutex;
	wxCondition m_notEmpty;
	wxCondition m_allTaskDone;

	bool m_killing;
	bool m_valid;

	wxMutex m_mutexWorker;
	wxCondition m_workerKill;

	int m_longTaskCount;

private:
	friend class wxiWorkThread;
	DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxiWorkerManager);
};
#endif